/**
 * @author gzz
 * 
 * 
 */
package edu.zju.jeigen;

public class MatXd implements Cloneable {
	// 构造函数
	public MatXd() {
		
	}

	public MatXd(final int row, final int cow) {
		setShape(row, cow);
	}

	public MatXd(double[][] val) {
		ele = val;
	}

	@Override
	public String toString() {
		StringBuilder str = new StringBuilder();

		for (int i = 0; i < ele.length; i++) {
			for (int j = 0; j < ele[i].length; j++) {
				str.append(String.valueOf(ele[i][j]) + "\t");
			}
			str.append("\n");
		}
		return str.toString();
	}

	// 设置矩阵的维数
	public void setShape(final int row, final int cow) throws OutOfMemoryError {
		ele = new double[row][cow];
	}

	// 设置矩阵元素值
	public void setValueAt(final int row, final int cow, double val) throws IndexOutOfBoundsException {
		ele[row][cow] = val;
	}

	// 赋值
	public void assign(double[][] val) {
		ele = val;
	}

	// 从文件中读入矩阵
	public void loadFromFile(String fname) {

	}

	// 返回矩阵元素
	public double get(final int row, final int cow) throws NullPointerException {
		return ele[row][cow];
	}

	public int getRow() {
		return ele == null ? 0 : ele.length;
	}

	public int getCow() {
		return ele == null ? 0 : ele[0].length;
	}

	// 矩阵运算
	public MatXd add(final MatXd... a) {
		setShape(a[0].getRow(), a[0].getCow());

		for (int k = 0; k < a.length; k++) {
			for (int i = 0; i < a[k].ele.length; i++) {
				for (int j = 0; j < a[k].ele[i].length; j++) {
					this.ele[i][j] += a[k].ele[i][j];
				}
			}
		}

		return this;
	}

	public MatXd sub(final MatXd... a) {
		setShape(a[0].getRow(), a[0].getCow());

		for (int k = 0; k < a.length; k++) {
			for (int i = 0; i < a[k].ele.length; i++) {
				for (int j = 0; j < a[k].ele[i].length; j++) {
					this.ele[i][j] -= a[k].ele[i][j];
				}
			}
		}

		return this;
	}

	public MatXd multiply(final double a) {

		for (int i = 0; i < this.ele.length; i++) {
			for (int j = 0; j < this.ele[i].length; j++) {
				this.ele[i][j] *= a;
			}
		}

		return this;
	}

	public MatXd division(final double... a) {

		for (int k = 0; k < a.length; k++) {
			for (int i = 0; i < this.ele.length; i++) {
				for (int j = 0; j < this.ele[i].length; j++) {
					this.ele[i][j] /= a[k];
				}
			}
		}

		return this;
	}

	@Override
	protected MatXd clone() throws CloneNotSupportedException {
		MatXd m = (MatXd) super.clone();
		m.ele = this.ele.clone();

		return m;
	}

	// data
	protected double[][] ele;
}
